package org.proteored.miapeapi.xml.pride.adapter;

import java.util.List;

import org.apache.log4j.Logger;
import org.proteored.miapeapi.cv.ControlVocabularyManager;
import org.proteored.miapeapi.cv.HumanDisseases;
import org.proteored.miapeapi.cv.MainTaxonomies;
import org.proteored.miapeapi.cv.SampleInformation;
import org.proteored.miapeapi.cv.SampleProcessingStep;
import org.proteored.miapeapi.cv.TissuesTypes;
import org.proteored.miapeapi.interfaces.Adapter;
import org.proteored.miapeapi.interfaces.ms.MSAdditionalInformation;
import org.proteored.miapeapi.interfaces.ms.MiapeMSDocument;
import org.proteored.miapeapi.xml.pride.autogenerated.CvParamType;
import org.proteored.miapeapi.xml.pride.autogenerated.DescriptionType;
import org.proteored.miapeapi.xml.pride.autogenerated.ObjectFactory;
import org.proteored.miapeapi.xml.pride.autogenerated.UserParamType;
import org.proteored.miapeapi.xml.pride.util.PrideControlVocabularyXmlFactory;

public class SampleDescriptionAdapter implements Adapter<DescriptionType> {
	private static Logger log = Logger.getLogger("log4j.logger.org.proteored");
	private final ObjectFactory factory;
	private final ControlVocabularyManager cvManager;
	private final MiapeMSDocument miapeMS;
	private final PrideControlVocabularyXmlFactory prideCvUtil;

	public SampleDescriptionAdapter(ObjectFactory factory,
			ControlVocabularyManager cvManager, MiapeMSDocument mergedMiapeMS) {
		this.miapeMS = mergedMiapeMS;
		this.factory = factory;
		this.cvManager = cvManager;
		this.prideCvUtil = new PrideControlVocabularyXmlFactory(factory,
				cvManager);
	}

	@Override
	public DescriptionType adapt() {
		DescriptionType sampleDescription = factory.createDescriptionType();
		// not mandatories

		boolean thereIsData = false;
		if (this.miapeMS != null) {
			List<MSAdditionalInformation> addInfos = this.miapeMS
					.getAdditionalInformations();
			if (addInfos != null) {
				for (MSAdditionalInformation msAdditionalInformation : addInfos) {
					thereIsData = true;
					String value = msAdditionalInformation.getValue();
					String name = msAdditionalInformation.getName();
					log.info("Add info:'" + name + "'='" + value + "'");
					if (value != null
							&& !"".equals(value)
							&& (name.equalsIgnoreCase("comment") || name
									.equalsIgnoreCase("comments"))) {
						sampleDescription.setComment(value);
					} else {
						log.info("getting cvParam from SampleInformation in sample information");
						CvParamType cvParam = prideCvUtil.createCvParam(name,
								value,
								SampleInformation.getInstance(cvManager),
								HumanDisseases.getInstance(cvManager),
								TissuesTypes.getInstance(cvManager));

						if (cvParam == null) {
							log.info("getting cvParam from Taxonomies in sample information");

							cvParam = prideCvUtil.createCvParam(name, value,
									MainTaxonomies.getInstance(cvManager));
							if (cvParam == null
									&& name.equalsIgnoreCase("human")) {
								Object object = prideCvUtil
										.createCvParamOrUserParam(
												"Homo Sapiens", null,
												MainTaxonomies
														.getInstance(cvManager));
								if (object instanceof CvParamType)
									cvParam = (CvParamType) object;
							}

						}

						if (cvParam == null) {
							log.info("getting cvParam from sample processing step in sample information");
							cvParam = prideCvUtil
									.createCvParam(name, value,
											SampleProcessingStep
													.getInstance(cvManager));
							if (cvParam != null) {
								// skip it since now is captured in the
								// ProtocolAdapterFromExperiment class
								log.info("skipping the caturing of this cvParam since it will be captured in the protocol");
								continue;
							}
						}

						if (cvParam != null) {
							sampleDescription.getCvParamOrUserParam().add(
									cvParam);
							log.info("Added '" + cvParam.getName() + "'='"
									+ cvParam.getValue() + "' '"
									+ cvParam.getAccession()
									+ "' to the sample information");
						} else {
							if (msAdditionalInformation.getName().toLowerCase()
									.contains("digestion")
									&& msAdditionalInformation.getValue() != null) {
								// ignore this add info, since it has been
								// already taken for the sample prep protocol
								// step (see ProcolAdapter class)
								continue;
							}

							log.info("Add info is not recognized as a CV param in sample information");
							UserParamType userParam = prideCvUtil
									.createUserParam(name, value);
							sampleDescription.getCvParamOrUserParam().add(
									userParam);
						}

					}
				}
			}
		}
		if (!thereIsData) {
			UserParamType userParam = factory.createUserParamType();
			userParam.setName("Not provided");
			sampleDescription.getCvParamOrUserParam().add(userParam);
		}

		return sampleDescription;
	}
}
